package cn.fl.system.service.impl;

import cmm.comm.facade.upload.api.IUploadApiService;
import cmm.comm.facade.upload.condition.SysUlFilesRecQueryCondition;
import cmm.comm.facade.upload.constant.SysUlFilesRecConstant;
import cmm.comm.facade.upload.dto.SysUlFilesRecDTO;
import cmm.mid.core.framework.dto.DataResultDTO;
import cmm.mid.core.framework.page.Pager;
import cn.cmm.base.framework.constant.BaseConstant;
import cn.cmm.base.framework.constant.BaseExceptionConstant;
import cn.cmm.base.framework.exception.BaseException;
import cn.cmm.base.framework.utils.BaseLogUtils;
import cn.cmm.base.framework.utils.CollectionUtils;
import cn.cmm.base.framework.utils.DateUtils;
import cn.cmm.base.framework.utils.StringUtils;
import cn.cmm.cache.framework.utils.PropertiesCacheUtils;
import cn.fl.framework.base.context.CurrentThreadContext;
import cn.fl.project.constant.PrjBscInfoConstant;
import cn.fl.project.service.IPrjBscInfoService;
import cn.fl.project.vo.PrjBscInfoVO;
import cn.fl.system.service.ISysUlFilesRecService;
import cn.fl.system.transform.SysUlFilesRecVOTransform;
import cn.fl.system.utils.FileTypeUtil;
import cn.fl.system.vo.SysUlFilesRecVO;
import cn.fl.upload.constant.UploadConstant;
import cn.fl.warrant.utils.Base64Change;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import fl.spl.facade.framework.constant.SplSystemConstant;
import net.sf.json.JSONArray;
import net.sf.json.JSONException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

/**
 * @Description: 文件上传记录表 客户端服务层接口实现
 */
@Service
public class SysUlFilesRecServiceImpl implements ISysUlFilesRecService {

	/**
	 * 日志
	 */
	private static final Logger logger = LoggerFactory.getLogger(SysUlFilesRecServiceImpl.class);
	
	/**
	 * 自定义 API 暴露服务
	 */
	@Autowired
	private IUploadApiService uploadApiService;

	@Autowired
	private IPrjBscInfoService prjBscInfoService;

	@Override
	public SysUlFilesRecVO selectById(Long id) throws BaseException{
		if(StringUtils.isEmpty(id))return null;
		SysUlFilesRecDTO dto = this.uploadApiService.selectBySysUlFilesRecId(id);
		return SysUlFilesRecVOTransform.toVO(dto);
	}

	@Override
	public Long add(SysUlFilesRecVO entity) throws BaseException{
		if(null == entity){
			BaseLogUtils.info(logger, "add", "新增文件上传记录失败,文件上传记录对象为空.DATA:"+JSONObject.toJSONString(entity), CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		if(StringUtils.isEmpty(entity.getAbsLocPath())){
			String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
			entity.setAbsLocPath(rootPath + entity.getFilePath());
		}
		return this.uploadApiService.addSysUlFilesRec(SysUlFilesRecVOTransform.toDTO(entity));
	}

	@Override
	public boolean removeByIds(List<Long> ids) throws BaseException {
		if(CollectionUtils.isEmpty(ids)){
			BaseLogUtils.info(logger, "removeByIds", "删除文件上传记录失败,主键参数为空.IDS:"+JSONObject.toJSONString(ids), CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		};
		return this.uploadApiService.removeSysUlFilesRecByIds(ids);
	}
	
	@Override
	public boolean modify(SysUlFilesRecVO entity) throws BaseException{
		if(null == entity)return false;
		if(StringUtils.isEmpty(entity.getAbsLocPath())){
			String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
			entity.setAbsLocPath(rootPath + entity.getFilePath());
		}
		return this.uploadApiService.modifySysUlFilesRecIsDelCdById(entity.getId(), String.valueOf(entity.getIsDel()));
		//return false;
	}
	
	@Override
	public List<SysUlFilesRecVO> searchList(
			SysUlFilesRecQueryCondition condition) throws BaseException {
		if(null==condition || StringUtils.isBlank(condition.getSysCd())){
			BaseLogUtils.info(logger, "searchList", "查询所有文件上传记录失败,系统代码为空.DATA:"+JSONObject.toJSONString(condition), CurrentThreadContext.getCurrentUserName());
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		List<SysUlFilesRecDTO> list = this.uploadApiService.searchSysUlFilesRecList(condition);
		//这里判断如果没有http开头的文件路径则把IP路径赋值
		if(CollectionUtils.isNotEmpty(list)){
			String serverPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_SERVER_PATH);
			for (SysUlFilesRecDTO sysUlFilesRecDTO : list) {
				String path = sysUlFilesRecDTO.getFilePath();
				//sysUlFilesRecDTO.setFilePath(path.replace(serverPath, ""));
				if(StringUtils.isEmpty(path) || path.startsWith("http") || StringUtils.isEmpty(serverPath))continue;
				sysUlFilesRecDTO.setFilePath(serverPath + path);
			}
		}
		return SysUlFilesRecVOTransform.toVOList(list);
	}

	@Override
	public JSONArray fileUpload(String modulePath,MultipartHttpServletRequest multipartRequest,String uploadSignStr) throws BaseException {
		BaseLogUtils.info(logger, "upload", "文件上传B1,上传标识["+uploadSignStr+"]", CurrentThreadContext.getCurrentUserName());
		JSONArray fileParams = new JSONArray();
		Long uploadSign = Long.valueOf(uploadSignStr.split("-")[0]);
		//获取文件 存储位置
		//String modulePath = multipartRequest.getParameter("filePath");//前端传过来的文件模块路径
		String sysCd = multipartRequest.getParameter("sysCd");//系统，即附件配置表
		String opTypCd = multipartRequest.getParameter("opTypCd");//前端传过来的系统类型
		String verNo = multipartRequest.getParameter("verNo");//版本号
		String rootPath = multipartRequest.getParameter("rootPath");//上传根目录
		String costomerPath = multipartRequest.getParameter("costomerPath");//文档目录
		String uploadSysCd = multipartRequest.getParameter("uploadSysCd");//实际上传的系统目录
		String tabNm = multipartRequest.getParameter("tabNm");//实际上传表名称
		String orgCd = multipartRequest.getParameter("orgCd");//实际上传的组织架构code，即附件配置表

		BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B1,上传文件参数modulePath:["+modulePath+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());

		try {
			// 拼接存入路径-------->系统相对路径前缀 + 系统代码 + 模块(自定义) + 时间 + 文件
			String prifixPath = null ;
			if(StringUtils.isNotEmpty(rootPath)){
				prifixPath = PropertiesCacheUtils.getProperty(rootPath);// 根目录
			}else{
				prifixPath = PropertiesCacheUtils.getProperty(UploadConstant.UPLOAD_ROOT_PATH); // 根目录
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B1,上传文件参数prifixPath:["+prifixPath+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());
			StringBuffer savePath = new StringBuffer(prifixPath);// 最终保存路径
			if (!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)) {// 判断是否以"/"结尾,不是加入斜杠
				savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B1,上传文件参数savePath-1:["+savePath.toString()+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());
			if(StringUtils.isNotEmpty(costomerPath)){ //文档目录
				costomerPath = PropertiesCacheUtils.getProperty(costomerPath) ;
				String[] cPath = costomerPath.split("/");
				if(cPath.length > 1){
					if(StringUtils.isNotEmpty(uploadSysCd)){
						costomerPath = cPath[0]+SysUlFilesRecConstant.SYS_FILE_PATH_SLASH+uploadSysCd+SysUlFilesRecConstant.SYS_FILE_PATH_SLASH;
					}
					savePath.append(costomerPath);
				}else{
					savePath.append(costomerPath);
					if(StringUtils.isEmpty(uploadSysCd)){
						savePath.append(CurrentThreadContext.getCurrentSysCd()).append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
					}else {
						savePath.append(uploadSysCd).append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
					}
				}
			}else{
				savePath.append(PropertiesCacheUtils.getProperty(UploadConstant.UPLOAD_COSTOMER_PATH));// 自定义代码-其中包括系统代码
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B1,上传文件参数savePath-2:["+savePath.toString()+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());
			if (StringUtils.isNotEmpty(modulePath)) {// 如果不等于空则加入
				//modulePath = PropertiesCacheUtils.getProperty(modulePath);
				if (modulePath.startsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)) {// 判断是否以"/"开头
					savePath.append(modulePath.substring(1));
				} else {
					savePath.append(modulePath);
				}
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B1,上传文件参数savePath-3:["+savePath.toString()+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());
			if (!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)) {// 判断是否以"/"结尾
				savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B2,上传文件参数savePath:["+savePath.toString()+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());

			String currentTime = DateUtils.formatDateToString(new Date(), DateUtils.YYYYMMDD);
			savePath.append(currentTime);
			savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
			// 检查目录
			File pathFile = new File(savePath.toString());
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B3,上传文件参数savePath:["+savePath.toString()+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms", CurrentThreadContext.getCurrentUserName());
			if (!pathFile.exists()) {
				BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B32,文件不存在创建文件", CurrentThreadContext.getCurrentUserName());
				// 文件夹不存 创建文件
				boolean createPath = pathFile.mkdirs();
				if (!createPath) {
					BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B33, 创建文件目录失败!createPath:[" + createPath+"],当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
					throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "服务器附件目录未创建失败!");
				}
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B4, 文件目录已存在或已创建,当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms" , CurrentThreadContext.getCurrentUserName());

			Iterator<String> iter = multipartRequest.getFileNames();
			// 如果没有文件 抛出异常
			if (!iter.hasNext()) {
				BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传失败,未选中文件内容.当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "请选择要上传的文件!");
			}
			// 访问附件前缀地址
			// String serverPrefixPath =
			// PropertiesCacheUtils.getProperty(UploadConstant.UPLOAD_SERVER_PATH);
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传B.当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
			// 创建返回的集合
			String iterFileName = null;
			Long uploadFileSign = null ;
			while (iter.hasNext()) {
				iterFileName = iter.next();
				BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"].上传文件["+iterFileName+"]开始" , CurrentThreadContext.getCurrentUserName());
				// 取得上传文件
				List<MultipartFile> fileList = multipartRequest.getFiles(iterFileName);
				BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"].上传文件数量SIZE：["+(CollectionUtils.isNotEmpty(fileList) ? fileList.size(): "0")+"]" , CurrentThreadContext.getCurrentUserName());
				uploadFileSign = System.currentTimeMillis();
				int fileNum = 0 ;
				for (MultipartFile f : fileList) {
					++fileNum ;
					BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"]，当前文件NUM:"+fileNum+"开始.当前耗时："+(System.currentTimeMillis() - uploadFileSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
					if (f != null) {
						// 取得当前上传文件的文件名称
						String myFileName = f.getOriginalFilename();
						// 取得当前上传文件的大小
						// Long size = f.getSize();
						// 如果名称不为"",说明该文件存在，否则说明该文件不存在
						BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"]，当前文件NUM:"+fileNum+"，当前上传文件名称："+myFileName+"开始.当前耗时："+(System.currentTimeMillis() - uploadFileSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
						if (StringUtils.isNotEmpty(myFileName)) {
							JSONObject fileParam = new JSONObject();
							// String fileNameRel =
							// myFileName.substring(0,myFileName.lastIndexOf("."));
							/*
							 * if(size>SysUlFilesRecConstant.SYS_FILE_MAX_SIZE){
							 * BaseLogUtils.info(logger, "fileUpload",
							 * "文件上传失败,文件大小超过了最大字节.SIZE:"+size,
							 * CurrentThreadContext.getCurrentUserName()); throw
							 * new BaseException(BaseExceptionConstant.
							 * BASE_EXCEPTION_CODE_604,
							 * "["+fileNameRel+"]文件大小超过50M,不能上传!"); }
							 */
							String _ext = myFileName.substring(myFileName.lastIndexOf("."));
							String randomFileName = UUID.randomUUID().toString().replace("-", "");
							String fileName = randomFileName + _ext;
							// 定义上传路径
							String path = savePath.toString() + fileName;
							fileParam.put("fileNm", myFileName);
							String serverPath = /* serverPrefixPath + */ path.replace(prifixPath, "");
							fileParam.put("filePath", serverPath);
							fileParam.put("absLocPath", path);
							fileParams.add(fileParam);
							File localFile = new File(path);
							try {
								f.transferTo(localFile);
							}catch (Exception e){
								BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"]，当前文件NUM:"+fileNum+"，当前上传文件名称："+myFileName+"上传失败.文件内容fileParam["+ JSON.toJSONString(fileParam)+"]，共耗时："+(System.currentTimeMillis() - uploadFileSign)+"/ms" , CurrentThreadContext.getCurrentUserName(),e);
								continue;
							}
							BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"]，当前文件NUM:"+fileNum+"，当前上传文件名称："+myFileName+"上传完成.文件内容fileParam["+ JSON.toJSONString(fileParam)+"]，共耗时："+(System.currentTimeMillis() - uploadFileSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
						}
					}
				}
				BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传C-["+iterFileName+"]上传全部完成.当前耗时："+(System.currentTimeMillis() - uploadFileSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
				/*
				 * MultipartFile f = multipartRequest.getFile(iter.next()); if
				 * (f != null) { // 取得当前上传文件的文件名称 String myFileName =
				 * f.getOriginalFilename(); //取得当前上传文件的大小 //Long size =
				 * f.getSize(); // 如果名称不为"",说明该文件存在，否则说明该文件不存在 if
				 * (StringUtils.isNotEmpty(myFileName)) { JSONObject fileParam =
				 * new JSONObject(); //String fileNameRel =
				 * myFileName.substring(0,myFileName.lastIndexOf("."));
				 *//*
					 * if(size>SysUlFilesRecConstant.SYS_FILE_MAX_SIZE){
					 * BaseLogUtils.info(logger, "fileUpload",
					 * "文件上传失败,文件大小超过了最大字节.SIZE:"+size,
					 * CurrentThreadContext.getCurrentUserName()); throw new
					 * BaseException(BaseExceptionConstant.
					 * BASE_EXCEPTION_CODE_604,
					 * "["+fileNameRel+"]文件大小超过50M,不能上传!"); }
					 *//*
					 * String _ext =
					 * myFileName.substring(myFileName.lastIndexOf(".")); String
					 * randomFileName =
					 * UUID.randomUUID().toString().replace("-", ""); String
					 * fileName = randomFileName + _ext; // 定义上传路径 String path =
					 * savePath.toString() + fileName; fileParam.put("fileNm",
					 * myFileName); String serverPath =
					 *//* serverPrefixPath + *//*
												 * path.replace(prifixPath, "");
												 * fileParam.put("filePath",
												 * serverPath);
												 * fileParams.add(fileParam);
												 * File localFile = new
												 * File(path);
												 * f.transferTo(localFile); } }
												 */
			}
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传D,上传全部完成.当前耗时："+(System.currentTimeMillis() - uploadSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
		} catch (BaseException ex) {
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传失败.ERROR", CurrentThreadContext.getCurrentUserName(),ex);
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, ex.getMessage());
		} catch (Exception ex) {
			BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传失败,系统错误.ERROR" ,CurrentThreadContext.getCurrentUserName(), ex);
			BaseLogUtils.error(logger, "fileUpload", "<"+uploadSignStr+">文件上传失败,系统错误.ERROR" ,CurrentThreadContext.getCurrentUserName(), ex);
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "系统异常!");
		}
		BaseLogUtils.info(logger, "fileUpload", "<"+uploadSignStr+">文件上传E,上传结束,返回参数fileParams:"+JSON.toJSONString(fileParams)+".共耗时："+(System.currentTimeMillis() - uploadSign)+"/ms" , CurrentThreadContext.getCurrentUserName());
		return fileParams;
	}
	
	@Override
	public void fileDownload(String id, String fileName, String filePath,HttpServletRequest request,HttpServletResponse response)
			throws BaseException {
		String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);

        String downLoadPath = rootPath + filePath;
		BufferedInputStream bis = null;  
		BufferedOutputStream bos = null;
		try {
			if(StringUtils.isNotEmpty(id)){
        		SysUlFilesRecVO sysUlFilesRecVO = this.selectById(Long.valueOf(id));
        		if(null != sysUlFilesRecVO){
        			String absLocPath = sysUlFilesRecVO.getAbsLocPath();
        			if(StringUtils.isNotEmpty(absLocPath)){
	        			downLoadPath = absLocPath;
	        			fileName = sysUlFilesRecVO.getFileNm();
        			}
        		}
        	}
			response.setContentType("text/html;charset=UTF-8");  
			request.setCharacterEncoding("UTF-8");
			File file = new File(downLoadPath);
			if (file.exists() && file.isFile()){  
		        long fileLength = file.length();  
				response.setContentType("application/x-msdownload;"); 
			    fileName = encodeChineseDownloadFileName(request, fileName);
			    BaseLogUtils.info(logger, "fileDownload", "转换中文内容：" + fileName);
			    response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("GBK"), "ISO8859-1"));
				response.setHeader("Content-Length", String.valueOf(fileLength));  
				bis = new BufferedInputStream(new FileInputStream(downLoadPath));  
				bos = new BufferedOutputStream(response.getOutputStream());  
				byte[] buff = new byte[2048];  
				int bytesRead;  
				while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {  
				    bos.write(buff, 0, bytesRead);  
				}
		    }else{  
		        logger.info(CurrentThreadContext.getCurrentUserName()+" file doesn't exist or is not a file -> name:" + fileName + " -> filePath:" + downLoadPath);  
		    }  
		} catch (BaseException ex) {
        	BaseLogUtils.info(logger, "fileDownload", "文件下载失败.ERROR:"+ex.getMessage(), CurrentThreadContext.getCurrentUserName());
			throw ex;
		}catch (Exception ex) {
			BaseLogUtils.error(logger, "fileDownload", "文件下载失败,系统错误.ERROR:"+ex.getMessage(), CurrentThreadContext.getCurrentUserName());
	    	throw new RuntimeException(ex);
		}finally {  
            if (bis != null)
				try {
					bis.close();
					bis = null;
				} catch (IOException e) {
					BaseLogUtils.error(logger, "-", "异常", e);
					throw new RuntimeException(e);
				}  
            if (bos != null)
				try {
					bos.close();
					bos = null;
				} catch (IOException e) {
					BaseLogUtils.error(logger, "-", "异常", e);
					throw new RuntimeException(e);
				}  
        }
	}
	
	/** 
     * 对文件流输出下载的中文文件名进行编码 屏蔽各种浏览器版本的差异性 
     * @throws UnsupportedEncodingException  
     */  
    private String encodeChineseDownloadFileName(  
            HttpServletRequest request, String pFileName) throws UnsupportedEncodingException {  
          
         String filename = null;    
            String agent = request.getHeader("USER-AGENT");    
            if (null != agent){    
                if (-1 != agent.indexOf("Firefox")) {//Firefox   
                	BaseLogUtils.info(logger, "encodeChineseDownloadFileName", "Firefox");
                    filename = "=?UTF-8?B?" + (new String(org.apache.commons.codec.binary.Base64.encodeBase64(pFileName.getBytes("UTF-8"))))+ "?=";    
                }else if (-1 != agent.indexOf("Chrome")) {//Chrome    
                	BaseLogUtils.info(logger, "encodeChineseDownloadFileName", "Chrome");
                    filename = new String(pFileName.getBytes(), "ISO8859-1");    
                } else {//IE7+   
                	BaseLogUtils.info(logger, "encodeChineseDownloadFileName", "IE7+");
                    filename = java.net.URLEncoder.encode(pFileName, "UTF-8");    
                    filename = org.apache.commons.lang.StringUtils.replace(filename, "+", "%20");//替换空格    
                }    
            } else {   
            	BaseLogUtils.info(logger, "encodeChineseDownloadFileName", "agent 未获取到!");
                filename = pFileName;    
            }    
            return filename;   
    } 

	@Override
	public boolean removeByCondition(SysUlFilesRecQueryCondition qc) throws BaseException {
		if(null==qc) return false;
		return uploadApiService.removeSysUlFilesRecByCondition(qc);
	}

	@Override
	public Boolean addAttchmnt(String id, String attchmnt,String cfgCd, String cfgDtlCd,
			String tabNm, String fileRem, String procInstId, String taskId, Boolean isDelOldData, String cfgOrgCd)throws BaseException {
		Boolean pass = false;
		if(StringUtils.isEmpty(id) || StringUtils.isEmpty(attchmnt)){
			return pass;
		}
		if(null == isDelOldData){//默认不删除
			isDelOldData = false;
		}
		try {
			JSONArray array = JSONArray.fromObject(attchmnt);
			if(null != array && !array.isEmpty() && array.isArray()){//处理附件
				List<SysUlFilesRecDTO> addList = new ArrayList<>();//需要新加的附件内容
				SysUlFilesRecDTO sysUlFilesRecDTO = null;//
				String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
				for (Object object : array) {
					net.sf.json.JSONObject upObj = net.sf.json.JSONObject.fromObject(object);
					String flPath = upObj.optString(SysUlFilesRecConstant.REQUEST_PARAM_FILE_PATH, SysUlFilesRecConstant.REQUEST_PARAM_DEFAULT_UNKNOW);
					String flNm = upObj.optString(SysUlFilesRecConstant.REQUEST_PARAM_FILE_NAME, SysUlFilesRecConstant.REQUEST_PARAM_DEFAULT_UNKNOW);
					sysUlFilesRecDTO = new SysUlFilesRecDTO();
					sysUlFilesRecDTO.setCrtTm(new Date());
					sysUlFilesRecDTO.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
					sysUlFilesRecDTO.setPkId(id);
					sysUlFilesRecDTO.setFileNm(flNm);
					sysUlFilesRecDTO.setFilePath(flPath);
					sysUlFilesRecDTO.setIsDel(BaseConstant.IS_YESNO_NO);
					sysUlFilesRecDTO.setSysCd(CurrentThreadContext.getCurrentSysCd());
					sysUlFilesRecDTO.setTransFlg(BaseConstant.IS_YESNO_NO);
					sysUlFilesRecDTO.setPInstId(procInstId);
					sysUlFilesRecDTO.setTInstId(taskId);
					sysUlFilesRecDTO.setCfgCd(cfgCd);
					sysUlFilesRecDTO.setCfgDtlCd(cfgDtlCd);
					sysUlFilesRecDTO.setFileRem(fileRem);
					sysUlFilesRecDTO.setOrgCd(cfgOrgCd);
					sysUlFilesRecDTO.setTabNm(tabNm);
					sysUlFilesRecDTO.setAbsLocPath(rootPath+flPath);
					addList.add(sysUlFilesRecDTO);
				}
				return this.uploadApiService.addSysUlFilesRecListWithIsDel(addList,isDelOldData);
			}else{
				pass = true;
			}
		}catch (JSONException e) {
			BaseLogUtils.info(logger, "addAttchmnt", "上传文件失败!" + e.getMessage());
		}catch (Exception e) {
			BaseLogUtils.error(logger, "addAttchmnt", "上传失败!" + e.getMessage());
		}
		return pass;
	}

	@Override
	public Boolean addSysUlFilesRecListWithIsDel(List<SysUlFilesRecDTO> list, boolean isDel) throws BaseException {
		try {
			if(CollectionUtils.isNotEmpty(list)){
				String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
				for (SysUlFilesRecDTO sysUlFilesRecDTO : list) {
					if(null == sysUlFilesRecDTO)continue;
					if(StringUtils.isEmpty(sysUlFilesRecDTO.getAbsLocPath())){
						sysUlFilesRecDTO.setAbsLocPath(rootPath + sysUlFilesRecDTO.getFilePath());
					}
				}
			}
			return this.uploadApiService.addSysUlFilesRecListWithIsDel(list,isDel);
		} catch (Exception e) {
			BaseLogUtils.error(logger, "addSysUlFilesRecListWithIsDel", "上传失败!" + e.getCause().getMessage());
		}
		return false;
	}
	
	 /**
     * 分页查询所有
     * zhangtong
     * @param page
     * @return
     */
	@Override
	public Pager searchListPage(Pager page) throws BaseException {
		 if (null == page) {
	            page = new Pager();
	            page.setCondition(new SysUlFilesRecQueryCondition());
	        }
		 
		
			Pager pager = 	this.uploadApiService.searchListPage(page);
			List<SysUlFilesRecDTO> list = (List<SysUlFilesRecDTO>) pager.getResultList();
					//这里判断如果没有http开头的文件路径则把IP路径赋值
					if(CollectionUtils.isNotEmpty(list)){
						String serverPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_SERVER_PATH);
						for (SysUlFilesRecDTO sysUlFilesRecDTO : list) {
							String path = sysUlFilesRecDTO.getFilePath();
							//sysUlFilesRecDTO.setFilePath(path.replace(serverPath, ""));
							if(StringUtils.isEmpty(path) || path.startsWith("http") || StringUtils.isEmpty(serverPath))continue;
							sysUlFilesRecDTO.setFilePath(serverPath + path);
						}
					}
					
					return pager;
	}
	/**
	 * post用base64传文件
	 */
	@Override
	public JSONArray fileUploadB64(String filePath,List<Map> fileList) throws BaseException {
		BaseLogUtils.info(logger, "fileUploadB64", "文件上传B1", CurrentThreadContext.getCurrentUserName());
		JSONArray fileParams = new JSONArray();
		try {
			// 拼接存入路径-------->系统相对路径前缀 + 系统代码 + 模块(自定义) + 时间 + 文件
			String prifixPath = PropertiesCacheUtils.getProperty(UploadConstant.UPLOAD_ROOT_PATH);// 根目录
			StringBuffer savePath = new StringBuffer(prifixPath);// 最终保存路径
			if (!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)) {// 判断是否以"/"结尾,不是加入斜杠
				savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
			}
			savePath.append(PropertiesCacheUtils.getProperty(UploadConstant.UPLOAD_COSTOMER_PATH));// 自定义代码-其中包括系统代码
			if (StringUtils.isNotEmpty(filePath)) {// 如果不等于空则加入
				if (filePath.startsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)) {// 判断是否以"/"开头
					savePath.append(filePath.substring(1));
				} else {
					savePath.append(filePath);
				}

			}
			BaseLogUtils.info(logger, "fileUploadB64", "文件上传B2", CurrentThreadContext.getCurrentUserName());
			if (!savePath.toString().endsWith(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH)) {// 判断是否以"/"结尾
				savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
			}
			String currentTime = DateUtils.formatDateToString(new Date(), DateUtils.YYYYMMDD);
			savePath.append(currentTime);
			savePath.append(SysUlFilesRecConstant.SYS_FILE_PATH_SLASH);
			BaseLogUtils.info(logger, "fileUploadB64", "文件上传B3", CurrentThreadContext.getCurrentUserName());
			// 检查目录
			File pathFile = new File(savePath.toString());
			BaseLogUtils.info(logger, "fileUploadB64", "文件上传B31->"+savePath.toString(), CurrentThreadContext.getCurrentUserName());
			if (!pathFile.exists()) {
				BaseLogUtils.info(logger, "fileUploadB64", "文件上传B32", CurrentThreadContext.getCurrentUserName());
				// 文件夹不存 创建文件
				boolean createPath = pathFile.mkdirs();
				if (!createPath) {
					BaseLogUtils.info(logger, "fileUploadB64", "文件上传B33, 创建文件目录失败!" + createPath, CurrentThreadContext.getCurrentUserName());
					throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "服务器附件目录未创建失败!");
				}
			}
			BaseLogUtils.info(logger, "fileUploadB64", "文件上传B4", CurrentThreadContext.getCurrentUserName());

			
			// 如果没有文件 抛出异常
			if (fileList==null||fileList.size()<1) {
				BaseLogUtils.info(logger, "filefileUploadB64", "文件上传失败,未选中文件内容.", CurrentThreadContext.getCurrentUserName());
				throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "请选择要上传的文件!");
			}
			// 访问附件前缀地址
			// String serverPrefixPath =
			// PropertiesCacheUtils.getProperty(fileUploadB64Constant.UPLOAD_SERVER_PATH);
			BaseLogUtils.info(logger, "fileUploadB64", "文件上传B", CurrentThreadContext.getCurrentUserName());
				// 取得上传文件
				for (Map f : fileList) {
					BaseLogUtils.info(logger, "fileUploadB64", "文件上传D", CurrentThreadContext.getCurrentUserName());
					if (f != null) {
						// 取得当前上传文件的文件名称
						String myFileName =(String) f.get("fileName");
						// 取得当前上传文件的大小
						// Long size = f.getSize();
						// 如果名称不为"",说明该文件存在，否则说明该文件不存在
						if (StringUtils.isNotEmpty(myFileName)) {
							JSONObject fileParam = new JSONObject();
							// String fileNameRel =
							// myFileName.substring(0,myFileName.lastIndexOf("."));
							/*
							 * if(size>SysUlFilesRecConstant.SYS_FILE_MAX_SIZE){
							 * BaseLogUtils.info(logger, "fileUpload",
							 * "文件上传失败,文件大小超过了最大字节.SIZE:"+size,
							 * CurrentThreadContext.getCurrentUserName()); throw
							 * new BaseException(BaseExceptionConstant.
							 * BASE_EXCEPTION_CODE_604,
							 * "["+fileNameRel+"]文件大小超过50M,不能上传!"); }
							 */
							String _ext = myFileName.substring(myFileName.lastIndexOf("."));
							String randomFileName = UUID.randomUUID().toString().replace("-", "");
							String fileName = randomFileName + _ext;
							// 定义上传路径
							String path = savePath.toString() + fileName;
							fileParam.put("fileNm", myFileName);
							String serverPath = /* serverPrefixPath + */ path.replace(prifixPath, "");
							fileParam.put("filePath", serverPath);
							fileParams.add(fileParam);
							String imgStr=(String)f.get("data");
							if(Base64Change.GenerateImage(imgStr, path)==false){
								return null;
							}
						}
					}
				}

			BaseLogUtils.info(logger, "fileUploadB64", "文件上传E", CurrentThreadContext.getCurrentUserName());
		} catch (BaseException ex) {
			BaseLogUtils.info(logger, "fileUploadB64", "文件上传失败.ERROR", CurrentThreadContext.getCurrentUserName(),ex);
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, ex.getMessage());
		} catch (Exception ex) {
			BaseLogUtils.error(logger, "fileUploadB64", "文件上传失败,系统错误.ERROR" ,CurrentThreadContext.getCurrentUserName(), ex);
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600, "系统异常!");
		}
		return fileParams;
	}

	/**
	 * 批量新增附件信息
	 * @param sysUlFilesRecVOs
	 * @return
	 * @throws BaseException
	 */
	@Override
	public boolean addSysUlFilesResList(List<SysUlFilesRecVO> sysUlFilesRecVOs) throws BaseException {
		if(CollectionUtils.isEmpty(sysUlFilesRecVOs)){
			BaseLogUtils.info(logger,"addSysUlFilesResList","批量新增附件信息，数据不能为空！");
			throw new BaseException(BaseExceptionConstant.BASE_EXCEPTION_CODE_600,BaseExceptionConstant.BASE_EXCEPTION_CODE_600_NAME);
		}
		return this.uploadApiService.addSysUlFilesRecList(SysUlFilesRecVOTransform.toDTOList(sysUlFilesRecVOs));
	}

	/**
	 * 根据条件修改附件信息
	 * @param condition 查询条件
	 * @param mdfMap 修改参数MAP
	 * @return
	 * @throws BaseException
	 */
	@Override
	public DataResultDTO updateSysUlFilesRecByQC(SysUlFilesRecQueryCondition condition, Map<String, Object> mdfMap) throws BaseException {
		DataResultDTO dataResultDTO = null ;
		BaseLogUtils.info(logger,"updateSysUlFilesRecByQC","根据条件更新附件信息接口，查询条件condition = ["+(null == condition? "{condition is NULL}" : JSONObject.toJSONString(condition))+"],更新条件mdfMap=["+(CollectionUtils.isMapEmpty(mdfMap) ? "{mdfMap is NULL}" :JSONObject.toJSONString(mdfMap))+"]");
		if(null == condition || CollectionUtils.isMapEmpty(mdfMap)){
			dataResultDTO = new DataResultDTO(String.valueOf(BaseConstant.IS_YESNO_NO));
			dataResultDTO.setInfo("查询条件或者更新条件为空！");
			BaseLogUtils.info(logger,"updateSysUlFilesRecByQC","根据条件更新附件信息接口，查询条件或者更新条件为空,更新失败！");
			return dataResultDTO;
		}
		dataResultDTO = this.uploadApiService.updateSysUlFilesRecByQC(condition,mdfMap,CurrentThreadContext.getCurrentSysCd(),CurrentThreadContext.getCurrentOrgCd(), SplSystemConstant.FL_WEB_CHL_CD);
		return dataResultDTO ;
	}

	@Override
	public Map<String, List<SysUlFilesRecVO>> getMultiList(String sysCd, String orgCd, String cfgCd,List<String> pkIdList) throws BaseException  {
		Map<String, List<SysUlFilesRecVO>> fileMap = new HashMap<>();
		if(CollectionUtils.isNotEmpty(pkIdList)){
			for (String pkId : pkIdList){
				List<SysUlFilesRecVO> list = new ArrayList<>();
				fileMap.put(pkId,list);
			}
		}
		SysUlFilesRecQueryCondition sysUlFilesRecQueryCondition = new SysUlFilesRecQueryCondition();
		sysUlFilesRecQueryCondition.setCfgCd(cfgCd);
		sysUlFilesRecQueryCondition.setOrgCd(orgCd);
		sysUlFilesRecQueryCondition.setSysCd(sysCd);
		sysUlFilesRecQueryCondition.setPkIdList(pkIdList);
		List<SysUlFilesRecVO> sysUlFilesRecVOList = this.searchList(sysUlFilesRecQueryCondition);
		if(CollectionUtils.isNotEmpty(sysUlFilesRecVOList)){
			for (SysUlFilesRecVO vo : sysUlFilesRecVOList){
				List<SysUlFilesRecVO> list = fileMap.get(vo.getPkId());
				if (null != list ){
					list.add(vo);
				}
				fileMap.put(vo.getPkId(),list);
			}
		}

		return fileMap;
	}

	@Override
	public void modifySysUlFilesRecList(List<SysUlFilesRecVO> list) throws BaseException {
		this.uploadApiService.modifySysUlFilesRecList(SysUlFilesRecVOTransform.toDTOList(list));
	}

	@Override
	public Boolean addAttchmntByOne(String id, String attchmnt, String cfgCd,
			String cfgDtlCd, String tabNm, String fileRem, String procInstId,
			String taskId, Boolean isDelOldData, String cfgOrgCd)
			throws BaseException {
		Boolean pass = false;
		if(StringUtils.isEmpty(id) || StringUtils.isEmpty(attchmnt)){
			return pass;
		}
		if(null == isDelOldData){//默认不删除
			isDelOldData = false;
		}
		try {
			List<SysUlFilesRecDTO> addList = new ArrayList<>();//需要新加的附件内容
			SysUlFilesRecDTO sysUlFilesRecDTO = null;//
			String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
			net.sf.json.JSONObject upObj = null;
			if(attchmnt.startsWith("{")){
				upObj = net.sf.json.JSONObject.fromObject(attchmnt);
			}else{
				net.sf.json.JSONArray array = net.sf.json.JSONArray.fromObject(attchmnt);
				upObj = array.getJSONObject(0);
			}
			String flPath = upObj.optString(SysUlFilesRecConstant.REQUEST_PARAM_FILE_PATH, SysUlFilesRecConstant.REQUEST_PARAM_DEFAULT_UNKNOW);
			String flNm = upObj.optString(SysUlFilesRecConstant.REQUEST_PARAM_FILE_NAME, SysUlFilesRecConstant.REQUEST_PARAM_DEFAULT_UNKNOW);
			sysUlFilesRecDTO = new SysUlFilesRecDTO();
			sysUlFilesRecDTO.setCrtTm(new Date());
			sysUlFilesRecDTO.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
			sysUlFilesRecDTO.setPkId(id);
			sysUlFilesRecDTO.setFileNm(flNm);
			sysUlFilesRecDTO.setFilePath(flPath);
			sysUlFilesRecDTO.setIsDel(BaseConstant.IS_YESNO_NO);
			sysUlFilesRecDTO.setSysCd(CurrentThreadContext.getCurrentSysCd());
			sysUlFilesRecDTO.setTransFlg(BaseConstant.IS_YESNO_NO);
			sysUlFilesRecDTO.setPInstId(procInstId);
			sysUlFilesRecDTO.setTInstId(taskId);
			sysUlFilesRecDTO.setCfgCd(cfgCd);
			sysUlFilesRecDTO.setCfgDtlCd(cfgDtlCd);
			sysUlFilesRecDTO.setFileRem(fileRem);
			sysUlFilesRecDTO.setOrgCd(cfgOrgCd);
			sysUlFilesRecDTO.setTabNm(tabNm);
			sysUlFilesRecDTO.setAbsLocPath(rootPath+flPath);
			addList.add(sysUlFilesRecDTO);
			return this.uploadApiService.addSysUlFilesRecListWithIsDel(addList,isDelOldData);
		}catch (JSONException e) {
			BaseLogUtils.info(logger, "addAttchmnt", "上传文件失败!" + e.getMessage());
		}catch (Exception e) {
			BaseLogUtils.error(logger, "addAttchmnt", "上传失败!" + e.getMessage());
		}
		return pass;
	}

    @Override
    public Boolean addAttchmntByOneSys(String id, String attchmnt, String cfgCd,
                                    String cfgDtlCd, String tabNm, String fileRem, String procInstId,
                                    String taskId, Boolean isDelOldData, String cfgOrgCd, String sysCd)
            throws BaseException {
        Boolean pass = false;
        if(StringUtils.isEmpty(id) || StringUtils.isEmpty(attchmnt)){
            return pass;
        }
        if(null == isDelOldData){//默认不删除
            isDelOldData = false;
        }
        try {
			BaseLogUtils.newWebLogger("===查询项目信息Start===prjId:" + id).info();
			PrjBscInfoVO prjBscInfoVO = this.prjBscInfoService.selectById(Long.valueOf(id));
			BaseLogUtils.newWebLogger("===查询项目信息End===prjId:" + id + ",prjBscInfoVO:" + JSON.toJSONString(prjBscInfoVO)).info();
			if (null == prjBscInfoVO) {
				return false;
			}
            List<SysUlFilesRecDTO> addList = new ArrayList<>();//需要新加的附件内容
            SysUlFilesRecDTO sysUlFilesRecDTO = null;//
            String rootPath = PropertiesCacheUtils.getProperty(SysUlFilesRecConstant.SYS_FILE_UPLOAD_ROOT_PATH);
			net.sf.json.JSONObject upObj = null;
			if(attchmnt.startsWith("{")){
				upObj = net.sf.json.JSONObject.fromObject(attchmnt);
			}else{
				net.sf.json.JSONArray array = net.sf.json.JSONArray.fromObject(attchmnt);
				upObj = array.getJSONObject(0);
			}
            String flPath = upObj.optString(SysUlFilesRecConstant.REQUEST_PARAM_FILE_PATH, SysUlFilesRecConstant.REQUEST_PARAM_DEFAULT_UNKNOW);
            String flNm = upObj.optString(SysUlFilesRecConstant.REQUEST_PARAM_FILE_NAME, SysUlFilesRecConstant.REQUEST_PARAM_DEFAULT_UNKNOW);
            sysUlFilesRecDTO = new SysUlFilesRecDTO();
            sysUlFilesRecDTO.setCrtTm(new Date());
            sysUlFilesRecDTO.setCrtUsrId(CurrentThreadContext.getCurrentUserId());
            sysUlFilesRecDTO.setPkId(id);
            sysUlFilesRecDTO.setFileNm(flNm);
            sysUlFilesRecDTO.setFilePath(flPath);
            sysUlFilesRecDTO.setIsDel(BaseConstant.IS_YESNO_NO);
            sysUlFilesRecDTO.setSysCd(CurrentThreadContext.getCurrentSysCd());
            if(StringUtils.isNotEmpty(sysCd)){
                sysUlFilesRecDTO.setSysCd(sysCd);
            }
            sysUlFilesRecDTO.setTransFlg(BaseConstant.IS_YESNO_NO);
            sysUlFilesRecDTO.setPInstId(procInstId);
            sysUlFilesRecDTO.setTInstId(taskId);
            sysUlFilesRecDTO.setCfgCd(cfgCd);
            sysUlFilesRecDTO.setCfgDtlCd(cfgDtlCd);
            sysUlFilesRecDTO.setFileRem(fileRem);
            sysUlFilesRecDTO.setOrgCd(cfgOrgCd);
            sysUlFilesRecDTO.setTabNm(tabNm);
            sysUlFilesRecDTO.setAbsLocPath(rootPath+flPath);
            if (PrjBscInfoConstant.PRJ_INS_CODE_QDGHBANK.equals(prjBscInfoVO.getInsCode())) {
				sysUlFilesRecDTO.setAudStsCd("3");
			}
            addList.add(sysUlFilesRecDTO);
            return this.uploadApiService.addSysUlFilesRecListWithIsDel(addList,isDelOldData);
        }catch (JSONException e) {
            BaseLogUtils.info(logger, "addAttchmnt", "上传文件失败!" + e.getMessage());
        }catch (Exception e) {
            BaseLogUtils.error(logger, "addAttchmnt", "上传失败!" + e.getMessage());
        }
        return pass;
    }
}
